/*
-----------------------------------------------------------------------------
Filename:    Bullet.cpp
Author: Michael Sebright
-----------------------------------------------------------------------------
Provides functions a Bullet object
Overides methods from Projectile 
*/

#include "Bullet.h"

/*
 * Bullet Constructer 
 */
Bullet::Bullet(SceneManager* sceneMgr) {
	 isActive = false; // bullet can be fired
	 velocity = BULLET_SPEED; // set bullet speed

	 /* create ribbon trail for bullet */
	NameValuePairList params;
	params["numberOfChains"] = "2";
	params["maxElements"] = "80";
	mTrail = (RibbonTrail*)sceneMgr->createMovableObject("RibbonTrail", &params);
	trailNode = sceneMgr->getRootSceneNode()->createChildSceneNode();
	trailNode->attachObject(mTrail);
	mTrail->setMaterialName("Examples/LightRibbonTrail");
	mTrail->setTrailLength(4);

	// Create a light node
	mProjectileNode = sceneMgr->getRootSceneNode()->createChildSceneNode();
	//lightNode = sceneMgr->getRootSceneNode()->createChildSceneNode();

	// Set initial settings for the ribbon mTrail and add the light node
	mTrail->setInitialColour(0, 0.7, 0.5, 0, 0.9);
	mTrail->setColourChange(0, 0.5, 0.5, 0.5, 0.5);
	mTrail->setInitialWidth(0, 0.8);
	mTrail->addNode(mProjectileNode);

	// Attach a light with the same colour to the light node
	light = sceneMgr->createLight();
	light->setDiffuseColour(mTrail->getInitialColour(0));
	light->setAttenuation(5,1,1,0);
	mProjectileNode->attachObject(light);

	// Attach a flare with the same colour to the light node
	bbs = sceneMgr->createBillboardSet(1);
	mLight1BBFlare = bbs->createBillboard(Vector3::ZERO, mTrail->getInitialColour(0));
	bbs->setMaterialName("Examples/Flare");
	mProjectileNode->attachObject(bbs);

	/* make bullet invisible to start */
	mTrail->setVisible(false);
	light->setVisible(false);
	bbs->setVisible(false);
}

Bullet::Bullet() {
}

/*
 * Set the bullet to be fire
 * initial position the position from where the bullet is to be fired
 * direction is the direction the bullet is to be fired in
 * direction can be altered based on a degree of ACCURAY which is randomy generated
 */
void Bullet::fire(Vector3 initialPosition, Quaternion direction) {
	Bullet::direction = direction; // set directon
	mProjectileNode->setPosition(initialPosition); // set posistion
	mProjectileNode->setOrientation(direction); // set orientation 

	/* get current time */
	GetSystemTime(&systemTime);
	srand(systemTime.wMilliseconds);

	/* get a degree of accuracy for where bullet while actally fire */
	accuracy = rand() % ACCURACY;
	if(rand() % 2) {
		accuracy *= -1;
	}
	
	/* set bullet to rotate by the accuracy offset */
	mProjectileNode->rotate(Vector3::UNIT_Y, Radian::Radian(accuracy));
	trailNode->rotate(Vector3::UNIT_Y, Radian::Radian(accuracy));


	mProjectileNode->scale(.1, .1, .1);
	mProjectileNode->translate(0,1,0);

	Bullet::direction = mProjectileNode->getOrientation(); // reset orientation 
	if(!rand() %4 ) {
		light->setVisible(true);
	}

	/* set bullet to be visiable */
	mTrail->setVisible(true);
	bbs->setVisible(true);
	isActive = true;
	
}

/*
 * Update function for Bullet
 * must be called after fire 
 * updates bullets location based on on its direction,  
 * location and time since last frame.
 * will set bullet inactive if it is no longer in frame
 */
void Bullet::update(Real deltaTime, Camera* cam) {
	mProjectileNode->translate(velocity * deltaTime * direction.zAxis().x, 0, velocity * deltaTime * direction.zAxis().z); // move bullet

	/* check to see if bullet is in frame */
	if(!cam->isVisible(mProjectileNode->_getWorldAABB())) {
		isActive = false; // bullet is not longer active 

		/* make bullet invisible */
		light->setVisible(false);
		mTrail->setVisible(false);
		bbs->setVisible(false);
	}
}

/*
 * Sets the bullet inactive and makes in invisible  
 */
void Bullet::setInactive() {
	isActive = false;
	light->setVisible(false);
	mTrail->setVisible(false);
	bbs->setVisible(false);
}

/*
 * Returns mProjectileNOde
 */
SceneNode* Bullet::getProjectileNode() {
	return mProjectileNode;
}